package com.ybe.handler.exchange;

import com.sun.net.httpserver.HttpExchange;
import com.ybe.exception.BadRequest;
import com.ybe.handler.exchange.annotation.HttpExchangeAnnotation;
import com.ybe.session.Session;
import com.ybe.session.SessionHolder;
import com.ybe.util.CommonUtil;
import com.ybe.util.HttpExchangeUtil;

import java.io.IOException;
import java.time.Instant;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@HttpExchangeAnnotation
public class SessionHandler implements HttpExchangeHandler {


    private static final Pattern SESSION_PATH = Pattern.compile("^/(\\d+)/session/?$");

    @Override
    public void handler(HttpExchange exchange) {
        String path = exchange.getRequestURI().getPath();
        Matcher m = SESSION_PATH.matcher(path);
        if (!m.matches()) {
            return;
        }
        try {
            int customerId = CommonUtil.parseInt(m.group(1));
            long now = System.currentTimeMillis();

            Session session = SessionHolder.getSessionById(customerId);
            if (session != null && !session.isExpired(now)) {
                session.refresh(now);
            } else {
                // 如果 session 已经过期 ，那么要主动删除
                if (session != null && session.isExpired(now)) {
                    SessionHolder.removeSession(session);
                }

                String key = SessionHolder.genSessionKey();
                Session sessionByKey = SessionHolder.getSessionByKey(key);
                //如果重新 生成的 sessionKey 已经 存在，那么需要重新再生成 sessionKey
                while (sessionByKey != null) {
                    key = SessionHolder.genSessionKey();
                    sessionByKey = SessionHolder.getSessionByKey(key);
                }
                session = new Session(customerId, key, now + SessionHolder.SESSION_TTL_MILLIS);
                SessionHolder.addSession(session);

                System.out.println("sessionKey:" + session.getKey() + " customerId:" + session.getCustomerId() + " expiresAt:" + Instant.ofEpochMilli(session.getExpiresAt()));
                HttpExchangeUtil.sendText(exchange, 200, session.getKey());
            }
        } catch (NumberFormatException e) {
            throw new BadRequest("customerId is not int type");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean isMatch(HttpExchange exchange) {
        String path = exchange.getRequestURI().getPath();
        final String method = exchange.getRequestMethod();
        return SESSION_PATH.matcher(path).matches() && "GET".equalsIgnoreCase(method);
    }
}
